package com.example.sicnuaccountingapp.base

import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.RecyclerView
import com.example.sicnuaccountingapp.R
import com.example.sicnuaccountingapp.ui.common.ItemAnimator
import com.example.sicnuaccountingapp.utils.AnimationUtils
import com.example.sicnuaccountingapp.utils.ErrorHandler
import com.example.sicnuaccountingapp.utils.TransitionUtils
import com.example.sicnuaccountingapp.utils.ViewUtils
import com.google.android.material.transition.MaterialSharedAxis
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch

abstract class BaseFragment : Fragment() {
    private var loadingView: View? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        loadingView = layoutInflater.inflate(R.layout.layout_loading, null)
    }

    protected fun <T> collectState(
        flow: Flow<UiState<T>>,
        onSuccess: (T) -> Unit
    ) {
        viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                flow.collect { state ->
                    when (state) {
                        is UiState.Loading -> showLoading()
                        is UiState.Success -> {
                            hideLoading()
                            onSuccess(state.data)
                        }
                        is UiState.Error -> {
                            hideLoading()
                            showError(state.error)
                        }
                        else -> hideLoading()
                    }
                }
            }
        }
    }

    private fun showLoading() {
        view?.let { rootView ->
            if (rootView is ViewGroup) {
                loadingView?.let { loadingView ->
                    ViewUtils.showLoading(rootView, loadingView)
                }
            }
        }
    }

    private fun hideLoading() {
        loadingView?.let { loadingView ->
            ViewUtils.hideLoading(loadingView)
        }
    }

    private fun showError(error: Throwable) {
        Toast.makeText(
            context,
            ErrorHandler.getErrorMessage(requireContext(), error),
            Toast.LENGTH_SHORT
        ).show()
    }

    protected fun setupRecyclerViewAnimation(recyclerView: RecyclerView) {
        recyclerView.itemAnimator = ItemAnimator()
        AnimationUtils.animateRecyclerView(recyclerView)
    }

    protected fun showLoadingWithAnimation() {
        view?.let { rootView ->
            if (rootView is ViewGroup) {
                loadingView?.let { loadingView ->
                    AnimationUtils.fadeIn(loadingView)
                }
            }
        }
    }

    protected fun hideLoadingWithAnimation() {
        loadingView?.let { loadingView ->
            AnimationUtils.fadeOut(loadingView)
        }
    }

    protected fun showViewWithAnimation(view: View) {
        AnimationUtils.fadeIn(view)
    }

    protected fun hideViewWithAnimation(view: View) {
        AnimationUtils.fadeOut(view)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        TransitionUtils.setupTransitions(this)
    }

    override fun postponeEnterTransition() {
        super.postponeEnterTransition()
        view?.doOnPreDraw { startPostponedEnterTransition() }
    }

    protected fun setupSharedAxisTransition(axis: Int = MaterialSharedAxis.X) {
        TransitionUtils.setupSharedAxisTransition(this, axis)
    }

    protected fun setupElevationScale() {
        TransitionUtils.setupElevationScale(this)
    }

    protected fun setupContainerTransform() {
        TransitionUtils.setupContainerTransform(this)
    }
} 